package org.smardi.fakeCall.Service;

import java.text.*;
import java.util.*;

import org.smardi.fakeCall.*;
import org.smardi.fakeCall.CLIQr.*;
import org.smardi.fakeCall.Caller.*;
import org.smardi.fakeCall.Setting.*;

import android.app.*;
import android.app.AlertDialog.Builder;
import android.app.PendingIntent.CanceledException;
import android.content.*;
import android.os.*;
import android.util.*;
import android.widget.*;

public class SV_FakeCall extends Service {

	public static final String ACTION_FAKECALL = "org.smardi.fakecall";
	public static final String ACTION_FAKECALL_NOTIFICATION_TIMER = "org.smardi.fakecall.notification.timer";
	public static final String ACTION_FAKECALL_DIALOG_TIMER_CANCEL = "org.smardi.fakecall.dialog_timer_cancel";
	public static final String ACTION_FAKECALL_TIMER_CANCEL = "org.smardi.fakecall.timer_cancel";
	public static final String ACTION_FAKECALL_CLIQ_ON = "org.smardi.fakecall.cliq_on";
	public static final String ACTION_FAKECALL_DIALOG_CLIQR_CANCEL = "org.smardi.fakecall.dialog_cliqr_cancel";
	public static final String ACTION_FAKECALL_CLIQR_CANCEL = "org.smardi.fakecall.cliqr_cancel";
	
	private final int WHAT_TIMER_REMAIN = 100;
	
	public long time_target = 0;	//알람을 울리는 목표 시간
	
	PendingIntent fakeCallIntent = null;
	
	//---------------------------------------------
	public class bsBinder extends Binder {
		public SV_FakeCall getService() {
			return SV_FakeCall.this;
		}
	}
	
	private final IBinder binder = new bsBinder();
	
	
	
	@Override
	public IBinder onBind(Intent intent) {
		
		return binder;
	}
	//---------------------------------------------
	
	AlarmManager AM = null;
	NotificationManager NM = null;
	
	Frequency mFreq = null;
	SharedPreference_FakeCall mPref = null;
	

	@Override
	public void onCreate() {
		super.onCreate();
		
		IntentFilter filter = new IntentFilter();
		filter.addAction(ACTION_FAKECALL);
		filter.addAction(ACTION_FAKECALL_NOTIFICATION_TIMER);
		filter.addAction(ACTION_FAKECALL_DIALOG_TIMER_CANCEL);
		filter.addAction(ACTION_FAKECALL_TIMER_CANCEL);
		filter.addAction(ACTION_FAKECALL_CLIQ_ON);
		filter.addAction(ACTION_FAKECALL_DIALOG_CLIQR_CANCEL);
		filter.addAction(ACTION_FAKECALL_CLIQR_CANCEL);
		filter.addAction(Frequency.ACTION_CLIQ_DETECTED);
		filter.addAction(Frequency.ACTION_CLIQ_NOT_DETECTED);
		registerReceiver(mReceiver, filter);
		
		NM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
		
		mFreq = Frequency.getInstance(SV_FakeCall.this, mHandler);
		mPref = new SharedPreference_FakeCall(SV_FakeCall.this);
		
		//Notification에 남은 시간을 표시하는 스레드 시작
		thread_Timer.start();
	}


	@Override
	public void onStart(Intent intent, int startId) {
		super.onStart(intent, startId);
		
		
	}
	
	
	@Override
	public void onDestroy() {
		super.onDestroy();
		
		unregisterReceiver(mReceiver);
	}


	//Broadcast Receiver
	BroadcastReceiver mReceiver = new BroadcastReceiver() {
		
		long time_cliq_detected_start = 0;
		long time_cliq_detected_end = 0;
		long time_cliq_not_detected_start = 0;
		long time_cliq_not_detected_end = 0;
		
		@Override
		public void onReceive(Context context, Intent intent) {
			if(intent.getAction().equals(ACTION_FAKECALL)) {
				time_target = 0;
				mPref.setTargetTime(0);
				NM.cancel(0);
				
				Intent fakeCallerIntent = new Intent(SV_FakeCall.this, AC_FakeCaller.class);
				fakeCallerIntent.putExtra("calling", true);
				PendingIntent fakeCallerPending = PendingIntent.getActivity(SV_FakeCall.this, 0, fakeCallerIntent, PendingIntent.FLAG_CANCEL_CURRENT);
				try {
					fakeCallerPending.send();
				} catch (CanceledException e) {
					e.printStackTrace();
				}
			}
			
			//--------------------------------------
			else if(intent.getAction().equals(ACTION_FAKECALL_NOTIFICATION_TIMER)) {
				time_target = intent.getLongExtra("time_target", 0);
				
				//알람 등록
				AM = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
				fakeCallIntent = PendingIntent.getBroadcast(
						SV_FakeCall.this, 0, new Intent(SV_FakeCall.ACTION_FAKECALL),
						PendingIntent.FLAG_ONE_SHOT);
				AM.set(AlarmManager.RTC_WAKEUP, time_target, fakeCallIntent);
				
				//Notification 만듬
				Notification notification = new Notification(R.drawable.ic_launcher, "FakeCall 시작", System.currentTimeMillis());
				notification.setLatestEventInfo(SV_FakeCall.this, "Fake", "Fake Call App", null);
				NM.notify(0, notification);
			}
			//--------------------------------------
			else if(intent.getAction().equals(ACTION_FAKECALL_DIALOG_TIMER_CANCEL)) {
				//Timer를 취소할건지 물어보는 다이얼로그 출력
				Intent popupIntent = new Intent(SV_FakeCall.this, AC_Dialog_Timer_Cancel.class);
				PendingIntent pi = PendingIntent.getActivity(SV_FakeCall.this, 0, popupIntent, PendingIntent.FLAG_ONE_SHOT);
				try {
					pi.send();
				} catch (CanceledException e) {
					e.printStackTrace();
				}
			}
			//--------------------------------------
			else if(intent.getAction().equals(ACTION_FAKECALL_TIMER_CANCEL)) {
				time_target = 0;
				mPref.setTargetTime(0);
				NM.cancel(0);
				AM.cancel(fakeCallIntent);
			}
			//--------------------------------------
			else if(intent.getAction().equals(ACTION_FAKECALL_CLIQR_CANCEL)) {
				NM.cancel(1);
				mPref.setCLIQrMode(false);
				mFreq.stopRecording();
			}
			//--------------------------------------
			else if(intent.getAction().equals(ACTION_FAKECALL_CLIQ_ON)) {
				
				PendingIntent pendingCLIQrNotification = PendingIntent.getBroadcast(SV_FakeCall.this, 0, new Intent(ACTION_FAKECALL_DIALOG_CLIQR_CANCEL), PendingIntent.FLAG_CANCEL_CURRENT);
				//Notification 만듬
				Notification notification = new Notification(R.drawable.ic_launcher, "CLIQ.r 감지 모드 켜짐", System.currentTimeMillis());
				notification.setLatestEventInfo(SV_FakeCall.this, "FakeCall", "CLIQ.r 감지 모드가 활성화 되었습니다", pendingCLIQrNotification);
				NM.notify(1, notification);
				
				mFreq.startRecording();
			}
			//--------------------------------------
			else if(intent.getAction().equals(ACTION_FAKECALL_DIALOG_CLIQR_CANCEL)) {
				Intent popupIntent = new Intent(SV_FakeCall.this, AC_Dialog_CLIQr_Cancel.class);
				PendingIntent pi = PendingIntent.getActivity(SV_FakeCall.this, 1, popupIntent, PendingIntent.FLAG_ONE_SHOT);
				try {
					pi.send();
				} catch (CanceledException e) {
					e.printStackTrace();
				}
			}
			//--------------------------------------
			else if(intent.getAction().equals(Frequency.ACTION_CLIQ_DETECTED)) {
				if(mFreq.isCliqrTesting == true) {
					//테스트 중일 때에는 동작하지 않는다
					return;
				}
				
				if(time_cliq_detected_start == 0) {
					time_cliq_detected_start = new Date().getTime();
				} else {
					time_cliq_detected_end = new Date().getTime();
				}
				
				time_cliq_not_detected_end = 0;
				time_cliq_not_detected_start = 0;
				
				
				if(time_cliq_detected_end - time_cliq_detected_start > 700) {
					//클리커 트리져드
					Intent fakeCallerIntent = new Intent(SV_FakeCall.this, AC_FakeCaller.class);
					fakeCallerIntent.putExtra("calling", true);
					fakeCallerIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
					PendingIntent fakeCallerPending = PendingIntent.getActivity(SV_FakeCall.this, 0, fakeCallerIntent, PendingIntent.FLAG_CANCEL_CURRENT);
					try {
						fakeCallerPending.send();
					} catch (CanceledException e) {
						e.printStackTrace();
					}
				}
			}
			//--------------------------------------
			else if(intent.getAction().equals(Frequency.ACTION_CLIQ_NOT_DETECTED)) {
				if(time_cliq_not_detected_start == 0) {
					time_cliq_not_detected_start = new Date().getTime();
				} else {
					time_cliq_not_detected_end = new Date().getTime();
				}
				
				if(time_cliq_not_detected_end - time_cliq_not_detected_start > 500) {
					time_cliq_detected_start = 0;
					time_cliq_detected_end = 0;
				}
			}
			//--------------------------------------
			else if(intent.getAction().equals(Frequency.ACTION_MIC_DO_NOT_WORK)) {
				NM.cancel(1);
				mPref.setCLIQrMode(false);
				mFreq.stopRecording();
				
				time_target = 0;
				mPref.setTargetTime(0);
				NM.cancel(0);
				AM.cancel(fakeCallIntent);
				
				//경고창을 띄운다
				Toast.makeText(SV_FakeCall.this, "마이크를 다른 프로그램이 사용하고 있습니다.\n해당 프로그램을 종료하셔야 FakeCall 앱을 이용하실 수 있습니다.", Toast.LENGTH_LONG).show();
			}
		}
	};
	
	
	//====================================================================
	Handler mHandler = new Handler(new Handler.Callback() {
		
		@Override
		public boolean handleMessage(Message msg) {
			
			switch(msg.what) {
			case WHAT_TIMER_REMAIN:
				
				PendingIntent intent = PendingIntent.getBroadcast(SV_FakeCall.this, 0, new Intent(ACTION_FAKECALL_DIALOG_TIMER_CANCEL), PendingIntent.FLAG_CANCEL_CURRENT);
				
				SimpleDateFormat dateFormat = new SimpleDateFormat(
						"(남은시간 ) HH:mm:ss");

				Notification notification = new Notification(
						R.drawable.ic_launcher, "FakeCall 시작", System
								.currentTimeMillis());
				notification
						.setLatestEventInfo(SV_FakeCall.this, "FakeCall",
								dateFormat.format(new Date(((Long) msg.obj)
										.longValue())), intent);
				NM.notify(0, notification);
				break;
			}
			return false;
		}
	});
	
	
	//====================================================================
	/**
	 * CLIQ.r 에 관련된 기능을 수행할 스레드
	 */
	Thread thread_CLIQ = new Thread(new Runnable() {
		@Override
		public void run() {
			// TODO Auto-generated method stub
			
		}
	});
	
	/**
	 * Notification에 남은 시간을 표시하기 위한 스레드
	 */
	Thread thread_Timer = new Thread(new Runnable() {
		long time_old = 0;
		
		@Override
		public void run() {
			while (true) {
				
				if(0 < time_target) {
				
					long time_now = new Date().getTime();	//현재시간
					long time_remain = time_target - time_now;	//남은 시간 계산
					
					if(950 < time_now - time_old && time_remain % 1000 < 50) {
						
						Date tempDate = new Date(14, 03, 18);
						
						Message msg = new Message();
						msg.what = WHAT_TIMER_REMAIN;
						msg.obj = (tempDate.getTime() + time_remain);
						mHandler.sendMessage(msg);
						
						time_old = time_now;
						
						
					
					}
				}
				
				try {
					Thread.sleep(40);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	});
	
}
